package com.bruce.codeFactory.Thread.designMode.ThreadWoker;

import java.util.Arrays;

/**
 * @author luotuan
 * @Description
 * @create 2019-03-13 21:50
 **/
public class Channel {
    private final Request[] requestQueue;
    private final static int MAX_REQUEST = 100;
    private int head;
    private int tail;
    private final WorkerThread[] wokerPool;
    private int count;

    public Channel(int workerSize) {
        this.requestQueue = new Request[MAX_REQUEST];
        this.head = 0;
        this.tail = 0;
        this.wokerPool = new WorkerThread[workerSize];
        init();
    }

    private void init() {
        for(int i=0;i<wokerPool.length;i++){
            wokerPool[i] = new WorkerThread("Worker_"+i,this);
        }
    }

    public void startWorker(){
        Arrays.asList(wokerPool).forEach(WorkerThread::start);
    }

    public synchronized void put(Request request) {
        while (count >= MAX_REQUEST) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        requestQueue[tail] = request;
        this.tail = (this.tail + 1) % requestQueue.length;
        this.count++;
        notifyAll();
    }

    public synchronized Request take() {
        while (count <= 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Request request = requestQueue[this.head];
        this.head = (this.head+1)%this.requestQueue.length;
        this.count--;
        notifyAll();
        return request;
    }
}
